# -*- coding: utf-8 -*-
"""
Spyder 编辑器

神经网络入门
"""
import numpy as np
import scipy.special
import matplotlib.pyplot as plt


class neuralNetwork:
    
    def __init__(self,inputnodes,hiddennodes,outputnodes,learninggrate):
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        
        
        self.wih = np.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
        self.who = np.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
        #learning rate
        self.lr = learninggrate
        self.activation_function = lambda x: scipy.special.expit(x)
        
        pass
    
    def train(self,inputs_list,targets_list):
        inputs = np.array(inputs_list,ndmin=2).T
        targets = np.array(targets_list,ndmin=2).T
        
        hidden_inputs = np.dot(self.wih,inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        
        final_inputs = np.dot(self.who,hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        
        outputs_errors = targets - final_outputs
        hidden_errors = np.dot(self.who.T,outputs_errors)
        
        self.who += self.lr* np.dot((outputs_errors* final_outputs*(1.0 - final_outputs)),np.transpose(hidden_outputs))
        self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1 - hidden_outputs)),np.transpose(inputs))
    
    def query(self,inputs_list):
        inputs = np.array(inputs_list,ndmin=2).T
        
        hidden_inputs = np.dot(self.wih,inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = np.dot(self.who,hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs
    
    
input_nodes = 784
hidden_nodes = 100
output_nodes = 10

learning_rate = 0.3

n = neuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)

training_data_file = open('D:\学习\python\神经网络\mnist_train.csv','r')
training_data_list = training_data_file.readlines()
training_data_file.close()

#训练数据
times = 5
for i in range(times):
    for record in training_data_list:
        all_values = record.split(',')
        inputs = (np.asfarray(all_values[1:])/255.0*0.99) + 0.01
        
        targets = np.zeros(output_nodes) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs,targets)
    



scorecard = []
test_data_file = open('D:\学习\python\神经网络\mnist_test.csv','r')
test_data_list = test_data_file.readlines()
test_data_file.close()
    
#测试数据
for record in test_data_list:
    all_values = record.split(',')
    correct_lable = all_values[0]
    print('正确数字：%s' % correct_lable)
    inputs = (np.asfarray(all_values[1:])/255.0*0.99) + 0.01
    outputs = n.query(inputs)
    label = np.argmax(outputs)
    print('神经网络答案:%s' % label)
    if(int(label) == int(correct_lable)):
        scorecard.append(1)
    else:
        scorecard.append(0)